package net.cassite.daf4j.stream;

import net.cassite.daf4j.*;

import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * QueryIntStream,QueryLongStream,QueryDoubleStream的基类
 *
 * @param <E> 实体类型
 * @param <N> 元素类型(Integer,Long,Double)
 * @param <T> Stream类型
 */
public abstract class QueryNumStreamBase<E, N extends Comparable<N>, T extends QueryNumStreamBase<E, N, T>> extends QueryStreamBase<E, QueryNumStreamBase<E, N, T>> implements Iterable<N> {
        protected final DataComparable<N> data;

        protected QueryNumStreamBase(E entity, DataAccess dataAccess, AndOr andOr, QueryParameter parameter, DataComparable<N> data) {
                super(entity, dataAccess);
                this.data = data;
                this.andOr = andOr;
                this.parameter = parameter;
        }

        /**
         * 执行求平均值操作
         *
         * @return double类型的求平均值结果
         */
        @SuppressWarnings("unchecked")
        public double average() {
                return DataUtils.executeAvg(entity, andOr, parameter, (DataComparable<? extends Number>) data, dataAccess);
        }

        /**
         * 对Stream进行排序<br>
         * 若实体未实现SortedEntity,那么将使用构造时传入的DataComparable作排序依据.<br>
         * 若实现了SortedEntity则仍然以实体规定的排序方式为依据
         *
         * @return 排序后的Stream
         * @see SortedEntity
         */
        @Override
        @SuppressWarnings("unchecked")
        public T sorted() {
                try {
                        return (T) super.sorted();
                } catch (UnsupportedOperationException e) {
                        return (T) sorted(data.asc());
                }
        }

        @Override
        public Iterator<N> iterator() {
                String alias = "resultData";
                List<Map<String, Object>> list = dataAccess.projection(entity, andOr, new QueryParameterWithFocus(parameter, new Focus().focus(data, alias)));
                return new It<N>(list, alias);
        }

}
